--- a/vboxdrv/r0drv/linux/memobj-r0drv-linux.c
+++ b/vboxdrv/r0drv/linux/memobj-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Id: memobj-r0drv-linux.c 103604 2015-10-22 13:10:56Z bird $ */
+/* $Id: memobj-r0drv-linux.c 60457 2016-04-12 13:27:21Z vboxsync $ */
 /** @file
  * IPRT - Ring-0 Memory Objects, Linux.
  */
@@ -372,11 +372,17 @@
 #endif /* < 2.4.22 */
     pMemLnx->fContiguous = fContiguous;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
     /*
      * Reserve the pages.
+     * 
+     * Linux >= 4.5 with CONFIG_DEBUG_VM panics when setting PG_reserved on compound
+     * pages. According to Michal Hocko this shouldn't be necessary anyway because
+     * as pages which are not on the LRU list are never evictable.
      */
     for (iPage = 0; iPage < cPages; iPage++)
         SetPageReserved(pMemLnx->apPages[iPage]);
+#endif
 
     /*
      * Note that the physical address of memory allocated with alloc_pages(flags, order)
@@ -423,7 +429,12 @@
          */
         while (iPage-- > 0)
         {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
+            /*
+             * See SetPageReserved() in rtR0MemObjLinuxAllocPages()
+             */
             ClearPageReserved(pMemLnx->apPages[iPage]);
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
 #else
             MY_SET_PAGES_NOEXEC(pMemLnx->apPages[iPage], 1);
@@ -578,7 +589,11 @@
                 {
                     if (!PageReserved(pMemLnx->apPages[iPage]))
                         SetPageDirty(pMemLnx->apPages[iPage]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+                    put_page(pMemLnx->apPages[iPage]);
+#else
                     page_cache_release(pMemLnx->apPages[iPage]);
+#endif
                 }
 
                 if (pTask && pTask->mm)
@@ -1029,14 +1044,38 @@
         /*
          * Get user pages.
          */
-        rc = get_user_pages(pTask,                  /* Task for fault accounting. */
-                            pTask->mm,              /* Whose pages. */
-                            R3Ptr,                  /* Where from. */
-                            cPages,                 /* How many pages. */
-                            fWrite,                 /* Write to memory. */
-                            fWrite,                 /* force write access. */
-                            &pMemLnx->apPages[0],   /* Page array. */
-                            papVMAs);               /* vmas */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+        if (R0Process == RTR0ProcHandleSelf())
+            rc = get_user_pages(R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+        /*
+         * Actually this should not happen at the moment as call this function
+         * only for our own process.
+         */
+        else
+            rc = get_user_pages_remote(
+                                pTask,                  /* Task for fault accounting. */
+                                pTask->mm,              /* Whose pages. */
+                                R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) */
+            rc = get_user_pages(pTask,                  /* Task for fault accounting. */
+                                pTask->mm,              /* Whose pages. */
+                                R3Ptr,                  /* Where from. */
+                                cPages,                 /* How many pages. */
+                                fWrite,                 /* Write to memory. */
+                                fWrite,                 /* force write access. */
+                                &pMemLnx->apPages[0],   /* Page array. */
+                                papVMAs);               /* vmas */
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) */
         if (rc == cPages)
         {
             /*
@@ -1081,7 +1120,11 @@
         {
             if (!PageReserved(pMemLnx->apPages[rc]))
                 SetPageDirty(pMemLnx->apPages[rc]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
+            put_page(pMemLnx->apPages[rc]);
+#else
             page_cache_release(pMemLnx->apPages[rc]);
+#endif
         }
 
         up_read(&pTask->mm->mmap_sem);
